#include "fxcc/core/graph/directX11/interface.h"
#include "fxcc/core/graph/directX11/ImGuiWin32App.h"
#include "fxcc/core/AssertManager.h"
#include "fxcc/imgui/Editor.h"

using namespace fxcc::platform;
using namespace fxcc::graph;

//using BaseApp = fxcc::graph::directX11::Win32App;
using BaseApp = fxcc::imgui::graph::directX11::Win32App;

struct SimpleApp :public BaseApp
{
	glm::vec4 color;
	std::shared_ptr<fxcc::graph::directX11::MeshJack> m_Mesh;
	std::shared_ptr<fxcc::graph::directX11::Texture2DJack> m_Texture2D;
	std::shared_ptr<fxcc::graph::directX11::Effect3d> m_Effect3d;

	fxcc::graph::common::Camera camera;
	fxcc::graph::common::Transform transform;

	SimpleApp(const BaseApp::Desc& desc) :BaseApp(desc), color(glm::vec4(0.0f))
	{
	}
	bool Init() override
	{
		if (!BaseApp::Init())
		{
			ztclog::info("failed load base app");
			return false;
		}
		if (!InitResources())
		{
			ztclog::info("failed init resources");
			return false;
		}
		return true;
		
	}
	bool InitResources() 
	{
		camera.SetPosition(glm::vec3(5.0f, 5.f, 5.0f));
		camera.LookAt(glm::vec3(0.0f));

		m_Mesh = std::make_shared<fxcc::graph::directX11::MeshJack>(fxcc::graph::common::Geometry::CreateBox());

		const std::string fragCode = R"(

Texture2D m_Texture : register(t0); 

float4 main(PSInput input) : SV_Target
{
	float4 color = m_Texture.Sample(m_Texture2dSampler, input.tex);
	return color;
};
)";
		m_Effect3d = std::make_shared<fxcc::graph::directX11::Effect3d>(fragCode);
		ztclog::info("%s", m_Effect3d->FixedVertCode().c_str());

		fxcc::graph::common::Texture2DJack::Desc texDesc;
		texDesc.m_WICConfig.m_WICFlipY = false;
		texDesc.m_WICConfig.m_wicHdr = false;
		texDesc.m_WICConfig.m_wicPath = fxcc::AssertManager::GetAbsoluteFile("container.jpg");
		texDesc.m_WICConfig.m_wicReq = 4;
		texDesc.m_SampleType = fxcc::graph::common::SamplerType::_sampler_2d_default_;
		
		texDesc.m_DDSPath = fxcc::AssertManager::GetAbsoluteFile("Model/Sponza/sponza_curtain_blue_diff.dds");
		texDesc.m_Type = fxcc::graph::common::Texture2DJack::Desc::_DDS_;

		m_Texture2D = std::make_shared<fxcc::graph::directX11::Texture2DJack>(texDesc);
		return true;


	}
	void OnFrameRender() override
	{
		auto& rs = fxcc::graph::directX11::RenderStates::Inst();;

		m_RT->Begin();

		for (auto texture : m_RT->m_Textures) {
			g_pImmediateContext->ClearRenderTargetView(texture->m_RenderTargetView.Get(), &color.x);
		}
		g_pImmediateContext->ClearDepthStencilView(m_RT->m_DepthStencilTexture->m_DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);


		rs.SetSamplerStates();
		fxcc::graph::common::Effect3d::PassData passData(camera);
		fxcc::graph::common::Effect3d::ObjData objData(transform);
		m_Effect3d->Begin();
		m_Texture2D->PSSet(0);
		m_Effect3d->SetPassData(passData);
		m_Effect3d->SetObjData(objData);
		m_Effect3d->InstMeshJack(m_Mesh.get());
		m_Effect3d->End();
		m_RT->End();

		g_pImmediateContext->OMSetRenderTargets(1, g_pRenderTargetView.GetAddressOf(), nullptr);

		D3D11_VIEWPORT vp;
		vp.Width = static_cast<FLOAT>(m_Desc.m_Size.x);
		vp.Height = static_cast<FLOAT>(m_Desc.m_Size.y);
		vp.MinDepth = 0.0f;
		vp.MaxDepth = 1.0f;
		vp.TopLeftX = 0;
		vp.TopLeftY = 0;
		g_pImmediateContext->RSSetViewports(1, &vp);
		g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView.Get(), &color.x);



	}
	std::shared_ptr<fxcc::graph::directX11::RenderTargetJack> m_RT;

	void OnFramebuffersize(int w, int h) override
	{
		BaseApp::OnFramebuffersize(w, h);
		camera.SetAspect(m_Desc.Aspect());
		
		if(m_HasInitFlag)
		{
			fxcc::graph::common::RenderTargetJack::Desc desc(1, { w, h ,4, 0 });
			m_RT = std::make_shared<fxcc::graph::directX11::RenderTargetJack>(desc);
			
		}
		
	}
	void OnUpdate() override
	{
		BaseApp::OnUpdate();

		double elapsedTime = m_WinTimer.m_CurrentTime;

		color.x = std::sin(elapsedTime) * 0.5f + 0.5;
		color.y = std::sin(elapsedTime + 1.7887f) * 0.5f + 0.5;
		color.z = std::cos(elapsedTime) * 0.5f + 0.5;
		color.w = 1;

		camera.FreeMove(m_Input, m_WinTimer.DeltaTime());
	}

	fxcc::imgui::Editor editor;

	std::string name;
	void OnEdit() override
	{
		ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());

		ImGui::Begin("directX app");
		ImGui::Text("hello");
		editor.AddFrameBufferLH(m_RT->m_Textures[0]->GetTextureId());
		ImGui::End();

		ImGui::Begin("Edit basic");

		editor.EditInst<std::string>("name ", name);
		ImGui::End();

	}
};

int main()
{
	ztclog::pushFunction([](const ztclog::Line& line) {
		std::cout << line.m_Text << std::endl;
		});

	using _App = SimpleApp;
	using _Desc = fxcc::platform::common::App::Desc;

	_Desc desc;
	desc.m_Pos = glm::ivec2(100, 100);
	desc.m_Size = glm::ivec2(800, 600);;

	desc.m_Title = " directX11 graph data";
	std::shared_ptr<_App> _app = std::make_shared<_App>(desc);

	return _app->Run();

}